/*
 * Copyright (C) 2009 Leandro de Oliveira Aparecido <lehphyro@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.google.code.japa.example.blogger;

import static com.google.code.liquidform.LiquidForm.*;
import static com.google.code.liquidform.Parameters.*;

import java.util.*;

import org.slf4j.*;
import org.springframework.transaction.annotation.*;

import com.google.code.japa.*;
import com.google.code.japa.annotation.*;
import com.google.code.liquidform.*;

@Transactional
@AutomaticPersistence
public class Blogger {

	private Logger logger = LoggerFactory.getLogger(getClass());
	
	@RepositoryQuery(extent = true)
	private List<User> users;
	
	public Blogger() {
		users = new ArrayList<User>();
	}
	
	public User signUp(String email, String emailVerification,
	                   String password, String passwordVerification,
	                   String name) {
		logger.info("Signing [{}] up", email);
		User user = new User();
		
		// Should validate email and password verification, but for test purposes, it is not necessary
		user.setEmail(email);
		user.setPassword(password);
		user.setName(name);
		
		users.add(user);
		
		return user;
	}
	
	public void updateUserInfo(String email,
	                           String name,
	                           @RepositoryQuery(name = User.USER_BY_EMAIL) User user) {
		logger.info("Updating name of user [{}]", email);
		user.setName(name);
	}

	public void updateUserInfo(@RepositoryQuery(name = User.USER_BY_EMAIL, byExample = true) User user,
	                           String name) {
		logger.info("Updating name of user [{}]", user.getEmail());
		user.setName(name);
	}

	public Blog createBlog(@RepositoryQuery(name = User.USER_BY_EMAIL, byExample = true) User user,
	                       String identifier, String name) {
		logger.info("Creating blog for user [{}]", user.getEmail());
		Blog blog = new Blog();
		blog.setIdentifier(identifier);
		blog.setName(name);
		user.addBlog(blog);
		
		return blog;
	}
	
	@RepositoryReturn(name = User.USER_BY_EMAIL_AND_PASSWORD, empty = UserNotFoundException.class)
	public User login(String email, String password) throws UserNotFoundException {
		if (email == null || password == null) {
			throw new UserNotFoundException();
		}
		// Transform the password before query
		return new User(email, "-==" + password + "==-");
	}

	public List<Blog> getAllRecentlyCommentedBlogs(int days) {
		Calendar calendar = Calendar.getInstance();
		calendar.add(Calendar.DAY_OF_MONTH, -days);
		
		Blog blog = alias(Blog.class, "blog");
		BlogEntry blogEntry = alias(blog.getEntries(), "blogEntry");
		Comment comment = alias(blogEntry.getComments(), "comment");
		
		SubQuery<Blog> query = select(blog).from(Blog.class).as(blog)
			.innerJoin(blog.getEntries()).as(blogEntry)
			.innerJoin(blogEntry.getComments()).as(comment)
			.where(lte(comment.getDate(), param(1, Date.class)));
		
		return Repository.query(query, calendar.getTime());
	}
	
// Getters/Setters

	public List<User> getUsers() {
		return users;
	}
	
	public void setUsers(List<User> users) {
		this.users = users;
	}
	
}
